import { RefIndex } from '../util/ref-index'
import type { Routing } from '../routing'
import type { Aircraft } from '../aircraft'
import type { FlightPlan } from './types'
import { getFlightPlanInfoList, type FlightPlanInfo } from './fpl-info'
import type { Ref } from '../base'
import type { Airport } from '../airport'

export let flightPlanByRouting: RefIndex<Routing, FlightPlan>
export let flightPlanByAircraft: RefIndex<Aircraft, FlightPlan>

export function initFlightPlanIndex(fplLst: FlightPlan[]) {
  flightPlanByRouting = new RefIndex(fplLst, (f) => f.routing)
  flightPlanByAircraft = new RefIndex(fplLst, (f) => f.aircraft)
}

export let aircraftFlightPlanInfos: Record<string, FlightPlanInfo[]>

const _empty: FlightPlanInfo[] = []

export function getAircraftFlightPlanInfo(ac: string): FlightPlanInfo[] {
  let record = aircraftFlightPlanInfos
  if (!record) {
    record = makeAircraftFlightPlanInfos()
    aircraftFlightPlanInfos = record
  }
  return record[ac] || _empty
}

function makeAircraftFlightPlanInfos(): Record<string, FlightPlanInfo[]> {
  const records: Record<string, FlightPlanInfo[]> = {}
  const fplLst = getFlightPlanInfoList()
  for (const fpl of fplLst) {
    let lst = records[fpl.aircraft]
    if (!lst) {
      lst = []
      records[fpl.aircraft] = lst
    }
    lst.push(fpl)
  }
  for (const lst of Object.values(records)) {
    lst.sort((f1, f2) => f1.startTime - f2.startTime)
  }
  return records
}

export interface AirportFlightPlanInfo {
  airport: string
  departure: FlightPlanInfo[]
  arrival: FlightPlanInfo[]
  list: FlightPlanInfo[]
}

let airportFlightPlanInfos: Record<Ref<Airport>, AirportFlightPlanInfo>

export function getAirportFlightPlanInfo(apt: Ref<Airport>): AirportFlightPlanInfo {
  let ais = airportFlightPlanInfos
  if (!ais) {
    airportFlightPlanInfos = makeAirportFlightPlanInfos()
    ais = airportFlightPlanInfos
  }
  let ret = ais[apt]
  if (!ret) {
    ret = {
      airport: apt,
      departure: [],
      arrival: [],
      list: []
    }
    ais[apt] = ret
  }
  return ret
}

function makeAirportFlightPlanInfos(): Record<Ref<Airport>, AirportFlightPlanInfo> {
  const fiLst = getFlightPlanInfoList()
  const ret: Record<string, AirportFlightPlanInfo> = {}
  for (const fi of fiLst) {
    if (fi.depApt) {
      let ai = ret[fi.depApt]
      if (!ai) {
        ai = {
          airport: fi.depApt,
          departure: [],
          arrival: [],
          list: []
        }
        ret[fi.depApt] = ai
      }
      ai.departure.push(fi)
      ai.list.push(fi)
    }
    if (fi.arrApt) {
      let ai = ret[fi.arrApt]
      if (!ai) {
        ai = {
          airport: fi.arrApt,
          departure: [],
          arrival: [],
          list: []
        }
        ret[fi.arrApt] = ai
      }
      ai.arrival.push(fi)
      ai.list.push(fi)
    }
  }
  for (const ai of Object.values(ret)) {
    ai.departure.sort((f1, f2) => f1.startTime - f2.startTime)
    ai.arrival.sort((f1, f2) => f1.startTime - f2.startTime)
    ai.list.sort((f1, f2) => f1.startTime - f2.startTime)
  }
  return ret
}
